<template>
	<div>
		<div v-if="type === 'status'">{{ statusEnum[status] }}</div>

		<template v-else>
			<a-space v-if="!targetId">
				<a-spin :indicator="indicator" />加载中...
			</a-space>
			<template v-else>
				<a-steps v-if="steps" direction="vertical" :current="stepCurrent" class="steps">
					<a-step v-for="(item) in stepOptions" :key="item.id">
						<template #title>
							<a-space>
								{{ item.title }}
								<small>
									<a-typography-text v-if="item.lowest" type="warning">（{{ item.lowest }} 人审批）</a-typography-text>
								</small>
							</a-space>
						</template>
						<template #description>
							<p v-if="(item?.roles || []).length">
								<a-typography-text>审批角色：{{ (item?.roles || []).map((d) => d.name).join('、') }}</a-typography-text>
								<br />
								<a-typography-text v-if="item?.auditors?.length">审批人：{{ (item?.auditors || []).map((d) => d.fullname).join('、') }}</a-typography-text>
							</p>

							<div v-for="(v, k) in item.desc" :key="k">
								<a-space>
									<a-typography-text type="secondary">{{ v.create_time }}</a-typography-text>
									<a-typography-text v-if="v.fullname">
										<img v-if="v.manually_signed_file_path" :src="v.manually_signed_file_path" height="40" />
										<span v-else>{{ v.fullname }}</span>
									</a-typography-text>
									<a-typography-text type="success">{{ v.status }}</a-typography-text>
									<a-typography-text v-if="v.remark" underline>意见：{{ v.remark }}</a-typography-text>
								</a-space>
								<!--
								<div>
									<a-space>
										<a-typography-text v-if="(v?.roles || []).length">审批角色：{{ (v?.roles || []).map((d) => d.name).join('、') }}</a-typography-text>
									</a-space>
								</div>
								<div v-if="v?.auditors?.length">
									<a-space>
										<a-typography-text>审批人：{{ (v?.auditors || []).map((d) => d.fullname).join('、') }}</a-typography-text>
									</a-space>
								</div>
								-->
							</div>
						</template>
					</a-step>
				</a-steps>

				<div v-if="type === 'submit'">
					<!--未提交-->
					<template v-if="status === -9">
						<a-button v-if="userInfo.id === userId" type="primary" @click="showSubmit">提交</a-button>
						<a-button v-else :disabled="true">待提交</a-button>
					</template>

					<!--驳回-->
					<template v-else-if="status === -1">
						<!--项目发起人拥有重新提交权限-->
						<a-space v-if="userInfo.id === userId">
							<a-button type="primary" @click="showSubmit">提交</a-button>

							<span v-if="extra" class="remark">
								审批状态：
								<a-tag color="red">驳回</a-tag>
								，驳回原因：{{ state.remark || '-' }}
							</span>
						</a-space>

						<a-button v-else disabled>驳回</a-button>
					</template>

					<!--未审批|审批中，判断当前用户是否拥有审批权限-->
					<template v-else-if="state.unauthorized === 0">
						<!--待审批-->
						<a-button v-if="status === 0" type="primary" @click="visible.audit = true">审批</a-button>

						<!--审批中需判断当前用户是否已参与审批-->
						<template v-if="status === 1">
							<a-button v-if="state.audited === 0" type="primary" @click="visible.audit = true">审批</a-button>
							<a-button v-else type="default" disabled>审批中</a-button>
						</template>
					</template>

					<!--没有审批权限-->
					<template v-else>
						<a-button type="default" disabled>{{ statusEnum[status] }}</a-button>
					</template>
				</div>
			</template>
		</template>

		<a-modal v-model:visible="visible.audit" title="审批结果" width="480px" @ok="handleAudit">
			<a-form ref="auditRef" :model="auditState" v-bind="{ labelCol: { style: { width: '100px' } } }">
				<a-form-item label="审批结果" :rules="{ required: true, message: '请选择审批结果' }" name="status">
					<a-radio-group v-model:value="auditState.status" @change="changeAuditStatus">
						<a-radio :value="1">通过</a-radio>
						<a-radio :value="-1" style="color:#f00">驳回</a-radio>
					</a-radio-group>
				</a-form-item>
				<a-form-item v-if="auditState.status === -1" label="驳回节点" :rules="{ required: true, message: '请选择驳回节点' }" name="next_node_id">
					<a-select v-model:value="auditState.next_node_id" placeholder="请选择驳回节点">
						<a-select-option v-for="item in nodeOptions" :key="item.value" :value="item.value">{{ item.label }}</a-select-option>
					</a-select>
				</a-form-item>

				<a-form-item v-if="nodeInfo.visible" label="选择审批人" name="notice_user_ids" :extra="`至少选择${nodeInfo.lowest}名审批人员`" :rules="{ required: true, validator: lowestValidator }">
					<a-select v-model:value="auditState.notice_user_ids" mode="multiple" :show-search="true" placeholder="请选择审批人员" allow-clear option-filter-prop="label">
						<a-select-option v-for="item in nodeInfo.users" :key="item.id" :value="item.id" :label="item.fullname">{{ item.fullname }}</a-select-option>
					</a-select>
				</a-form-item>

				<a-form-item label="审批意见" name="remark">
					<a-textarea v-model:value="auditState.remark" :rows="4" placeholder="请输入审批意见"></a-textarea>
				</a-form-item>
			</a-form>
		</a-modal>

		<!--提交界面-->
		<a-modal v-model:visible="visible.submit" title="提交审核" width="480px" @ok="handleSubmit">
			<a-form ref="submitRef" :model="submitState" v-bind="{ labelCol: { style: { width: '100px' } } }">
				<a-form-item label="选择审批人" name="notice_user_ids" :extra="`至少选择${nodeInfo.lowest || '-'}名审批人员`" :rules="{ required: true, validator: lowestValidator }">
					<a-select v-model:value="submitState.notice_user_ids" mode="multiple" :show-search="true" placeholder="请选择审批人员" allow-clear option-filter-prop="label">
						<a-select-option v-for="item in nodeInfo.users" :key="item.id" :value="item.id" :label="item.fullname">{{ item.fullname }}</a-select-option>
					</a-select>

					<!--
					<a-select v-model:value="submitState.notice_user_ids" :options="nodeInfo.users" mode="multiple" :show-search="true" placeholder="请选择审批人员" allow-clear option-filter-prop="fullname" :field-names="{ value: 'id', label: 'fullname' }"></a-select>
					-->
				</a-form-item>
			</a-form>
		</a-modal>
	</div>
</template>

<script setup>
import dayjs from "dayjs";
import { LoadingOutlined } from "@ant-design/icons-vue";
import { h } from "vue";
const indicator = h(LoadingOutlined, {
	style: {
		fontSize: "16px"
	},
	spin: true
});

import { post } from "../utils";

import { ref, onMounted, getCurrentInstance, watch, computed } from "vue";

const props = defineProps({
	type: {
		type: String,
		required: false,
		default() {
			//默认审批提交按钮
			return "submit";
		}
	},
	targetId: {
		type: [Number, String],
		required: false
	},

	//workflow_module.name
	module: {
		type: String,
		required: true
	},
	projectId: {
		type: Number,
		required: false
	},
	code: {
		type: String,
		required: false
	},

	status: {
		type: Number,
		required: false,
		default() {
			return -9;
		}
	},
	userId: {
		type: Number,
		required: false
	},
	extra: {
		type: Boolean,
		required: false,
		default() {
			return false;
		}
	},
	steps: {
		type: Boolean,
		required: false,
		default() {
			return false;
		}
	}
});

import { userStore } from "../store";
const store = userStore();
const userInfo = store.info;

const statusEnum = {
	"-9": "未提交",
	"-1": "驳回",
	//已提交（待审批）
	0: "待审批",
	1: "审批中",
	2: "通过"
};

const emit = defineEmits(["submit", "update:status"]);

const { proxy } = getCurrentInstance();

const state = ref({});

onMounted(async () => {});

watch(
	() => props.targetId,
	async value => {
		if (!value || (props.type === "status" && props.status === 2)) return;

		const { module, targetId: target_id } = props;
		state.value = await post("workflow/info", {
			module,
			target_id
		});

		//兼容一下旧数据
		if (!state.value.id && props.status === 2) return;

		//更新工作流状态
		const { status } = state.value;
		emit("update:status", status);
	},
	{ immediate: true, deep: true }
);

const nodeInfo = ref({});
const showSubmit = async () => {
	visible.value.submit = true;

	//获取第一个节点拥有审核权限的人员
	const { module, targetId: target_id, projectId: project_id } = props;

	const { nodes } = await post("workflow/module/info", { module, project_id });

	nodeInfo.value = nodes.find(({ step }) => step === 1);
};

const handleSubmit = () => {
	submitRef.value.validate().then(() => {
		proxy.$message.destroy();

		const { module, targetId: target_id, projectId: project_id, code } = props;
		const { notice_user_ids = [] } = submitState.value;

		post("workflow/submit", {
			target_id,
			module,
			project_id,
			code,
			notice_user_ids: notice_user_ids.join(",")
		}).then(data => {
			proxy.$message.success("提交成功");
			//@submit=""
			emit("submit", data);

			state.value = data;

			//v-model:status=""
			const { status } = state.value;
			emit("update:status", status);

			visible.value.submit = false;
		});
	});
};

const visible = ref({
	audit: false,
	submit: false
});
const auditRef = ref();
const auditState = ref({});

const submitRef = ref();
const submitState = ref({});

const handleAudit = () => {
	auditRef.value.validate().then(() => {
		proxy.$message.destroy();

		const { module, targetId: target_id } = props;
		const { notice_user_ids = [] } = auditState.value;
		post("workflow/audit", {
			...auditState.value,
			notice_user_ids: notice_user_ids.join(","),
			module,
			target_id
		})
			.then(data => {
				proxy.$message.success("审批提交成功");
				visible.value.audit = false;
				auditState.value = {};

				state.value = data;
				const { status } = state.value;
				emit("update:status", status);
			})
			.catch(err => {
				proxy.$message.error(err);
			});
	});
};

const nodeOptions = computed(() => {
	const nodes = [];

	nodes.push({
		value: -1,
		label: "发起人"
	});
	const { module, latest_node } = state.value;

	module.nodes.forEach(({ id, step, name }) => {
		if (step < latest_node.module_node.step) {
			nodes.push({
				value: id,
				label: name
			});
		}
	});

	return nodes;
});

const stepCurrent = ref(0);
const stepOptions = computed(() => {
	if (!Object.keys(state.value).length) return;

	const steps = [];

	state.value.nodes?.forEach(node => {
		const {
			id,
			module_node,
			users = [],
			module_node: { roles, lowest },
			auditors = []
		} = node;
		const { name } = module_node;
		const desc = [];

		if (!users.length) {
			desc.push({
				create_time: dayjs(node.create_time).format("YYYY-MM-DD HH:mm:ss"),
				fullname: "",
				status: "待审批",
				roles,
				lowest,
				auditors
			});
		} else {
			users.forEach(user => {
				const {
					status,
					create_time,
					remark,
					user: { fullname }
				} = user;
				desc.push({
					status: status === -1 ? "驳回" : status === 1 ? "通过" : status === 0 ? "审批中" : "",
					create_time: dayjs(create_time).format("YYYY-MM-DD HH:mm:ss"),
					remark,
					fullname,
					roles,
					lowest,
					auditors
				});
			});
		}

		steps.push({
			id,
			title: name,
			lowest,
			desc,
			roles,
			auditors
		});
	});

	stepCurrent.value = state.value.nodes?.findIndex(d => d.id === state.value.latest_node_id);

	return steps;
});

const lowestValidator = (rule, value) => {
	const { lowest } = nodeInfo.value;
	if ((value?.length || 0) < lowest) {
		return Promise.reject(`至少选择${lowest}名审批人员`);
	}

	return Promise.resolve(true);
};

const changeAuditStatus = async e => {
	const { module, projectId: project_id } = props;
	if (e.target.value === 1) {
		const {
			module_node: { step, lowest },
			users = []
		} = state.value.latest_node;
		if (lowest === users.length + 1) {
			//判断当前节点是否达到最低审批人数
			const { nodes } = await post("workflow/module/info", { module, project_id, step: step + 1 });
			const node = nodes.find(d => d.step === step + 1);
			node.visible = true;
			nodeInfo.value = node;
		}
	} else {
		nodeInfo.value.visible = false;
	}
};
</script>

<style scoped>
.remark {
	line-height: 20px;
	padding: 10px 0;
}

.steps {
	padding-bottom: 20px;
}
</style>